package com.mqy.spring.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 13159 //作者
 * @version V1.0 //版本
 * @Project 2022.3.4SpringProxy
 * @Package com.mqy.spring
 * @Description:
 * @Date 2022/3/4 14:43//日期
 * @Motto:放下杂念,只为迎接明天更好的自己
 */

/*事务*/
public class BeanFactory {
//    public static UserService getService() {
//        //最终执行的代码
//        UserServiceImpl userService = new UserServiceImpl();
//        /*proxy 是代理的意思
//         * newProxyInstance() 创建一个代理的实例
//         * userService.getClass().getClassLoader(),  第一个参数 类加载器
//         *  userService.getClass().getInterfaces()  创建什么类的代理对象
//         * new InvocationHandler() {.....}  执行器  使用代理器是具体要执行什么
//         * */
//        UserService o = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
//
//            /*invoke 当执行匿名内部类代理对象中的方法的时候没有具体操作,所以java将代码封装,然后执行当前方法
//             *proxy 匿名对象谁
//             *method 匿名对象正在执行什么方法
//             * args 匿名对象类传递的参数是什么
//             * */
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                System.err.println("匿名对象执行了" + method.getName() + "------BeanFactory中的方法invoke执行了");
//
//                /*开启事务*/
//                TransactionUtils.start();
//                /*执行原始代码  并获取原始结果*/
//                Object invoke = method.invoke(userService, args);
//                /*提交事务*/
//                TransactionUtils.commit();
//
//                /*日志*/
//                LogUtils.addLog();
//
//
//                return invoke;/*返回的原始结果*/
//            }
//        });
//        return o;
//    }

    public static <T> T getService(Class<T> clazz) throws Exception {
        //最终执行的代码
        //UserServiceImpl userService = new UserServiceImpl();
        T newInstance = clazz.newInstance();

        /*proxy 是代理的意思
         * newProxyInstance() 创建一个代理的实例
         * userService.getClass().getClassLoader(),  第一个参数 类加载器
         *  userService.getClass().getInterfaces()  创建什么类的代理对象
         * new InvocationHandler() {.....}  执行器  使用代理器是具体要执行什么
         * */
        T o = (T) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {

            /*invoke 当执行匿名内部类代理对象中的方法的时候没有具体操作,所以java将代码封装,然后执行当前方法
             *proxy 匿名对象谁
             *method 匿名对象正在执行什么方法
             * args 匿名对象类传递的参数是什么
             * */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.err.println("匿名对象执行了" + method.getName() + "------BeanFactory中的方法invoke执行了");

                /*开启事务*/
                TransactionUtils.start();
                /*执行原始代码  并获取原始结果*/
                Object invoke = method.invoke(newInstance, args);
                /*提交事务*/
                TransactionUtils.commit();

                /*日志*/
                LogUtils.addLog();


                return invoke;/*返回的原始结果*/
            }
        });
        return o;
    }
}













